package com.quectel.business.dms.device;

import com.quectel.business.common.device.DeviceExtraAttrCls;
import com.quectel.business.dms.AccessorUtils;
import com.quectel.business.dms.application.ApplicationBusiness;
import com.quectel.business.dms.application.access.accessor.im.AbstractIntelligentMonitorAccessor;
import com.quectel.business.dms.application.access.accessor.im.model.PlaybackPart;
import com.quectel.core.module.application.dto.ApplicationDto;
import com.quectel.core.module.device.dto.DeviceCategoryDto;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.dto.DeviceTypeDto;
import com.quectel.core.module.device.service.DeviceCategoryService;
import com.quectel.core.module.device.service.DeviceTypeService;
import com.quectel.util.common.JacksonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class DeviceIntegrationBusiness {

    @DubboReference
    private DeviceTypeService deviceTypeService;
    @DubboReference
    private DeviceCategoryService deviceCategoryService;
    @Autowired
    private ApplicationBusiness applicationBusiness;

    /**
     * 填充设备类型等关联字段
     *
     * @param deviceDto 需要填充的dto
     * @param typeCode  设备类型编码
     */
    public void fillCommonDataByTypeCode(DeviceDto deviceDto, String typeCode) {
        DeviceTypeDto deviceTypeDto = deviceTypeService.selectByCode(typeCode);
        fillCommonData(deviceDto, deviceTypeDto);

    }

    /**
     * 填充设备类型等关联字段
     *
     * @param deviceDto      需要填充的dto
     * @param applicationDto 应用dto
     */
    public void fillCommonDataByApp(DeviceDto deviceDto, ApplicationDto applicationDto) {
        deviceDto.setApplicationId(applicationDto.getId());
        deviceDto.setVillageId(applicationDto.getVillageId());
        deviceDto.setTenantId(applicationDto.getTenantId());

        DeviceTypeDto deviceTypeDto = deviceTypeService.selectCacheById(applicationDto.getDeviceTypeId());
        fillCommonData(deviceDto, deviceTypeDto);
    }

    private void fillCommonData(DeviceDto deviceDto, DeviceTypeDto deviceTypeDto) {
        if (deviceTypeDto != null) {
            deviceTypeDto = deviceTypeService.selectCacheById(deviceTypeDto.getId());
            deviceDto.setDeviceTypeId(deviceTypeDto.getId());
            deviceDto.setDeviceType(deviceTypeDto);

            DeviceCategoryDto deviceCategoryDto = deviceCategoryService.selectById(deviceTypeDto.getDeviceCategoryId());
            deviceDto.setDeviceCategoryId(deviceCategoryDto.getId());
            deviceDto.setDeviceCategory(deviceCategoryDto);
        }
    }

    /**
     * 填充监控设备的url
     *
     * @param list
     */
    public void fillDevicesStreamUrl(List<DeviceDto> list) {
        try {
            Map<Long, List<DeviceDto>> listMap = list.stream().collect(Collectors.groupingBy(DeviceDto::getDeviceTypeId));
            for (Long deviceTypeId : listMap.keySet()) {

                DeviceTypeDto deviceTypeDto = deviceTypeService.selectById(deviceTypeId);

                AbstractIntelligentMonitorAccessor intelligentMonitorAccessor = AccessorUtils.getIntelligentMonitorAccessor(deviceTypeDto);
                List<DeviceDto> deviceDtos = listMap.get(deviceTypeId);

                assert intelligentMonitorAccessor != null;
                List<String> streamUrls = intelligentMonitorAccessor.getH264HlsStreamUrls(deviceDtos);

                for (int i = 0; i < deviceDtos.size(); i++) {
                    DeviceExtraAttrCls.AttrOfIntelligentMonitor attr = DeviceExtraAttrCls.parseExtStr(DeviceExtraAttrCls.AttrOfIntelligentMonitor.class
                            , deviceDtos.get(i).getExtraAttr());
                    if (attr == null) {
                        attr = new DeviceExtraAttrCls.AttrOfIntelligentMonitor();
                    }
                    if (StringUtils.isNotBlank(streamUrls.get(i))) {
                        String streamUrl = streamUrls.get(i);
                        attr.setStreamUrl(streamUrl);
                    }
                    deviceDtos.get(i).setExtraAttr(JacksonUtils.toJsonString(attr));
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取时间范围内回放片段
     *
     * @param deviceDto 监控
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 回放片段列表
     */
    public List<PlaybackPart> getPlaybackPart(DeviceDto deviceDto, Date startTime, Date endTime) {
        DeviceTypeDto deviceTypeDto = deviceTypeService.selectById(deviceDto.getDeviceTypeId());
        List<PlaybackPart> playbackParts = new ArrayList<>();
        AbstractIntelligentMonitorAccessor intelligentMonitorAccessor = AccessorUtils.getIntelligentMonitorAccessor(deviceTypeDto);
        if (intelligentMonitorAccessor != null) {
            playbackParts = intelligentMonitorAccessor.getPlaybackParts(deviceDto, startTime, endTime);
        }
        return playbackParts;
    }
}
